<template>
  <div class="base">
    <canvas id="webgl"></canvas>
    <div class="pannel">
      <span>XZ：{{ x?.toFixed(2) }},{{ z?.toFixed(2) }}</span>
      <br />
      <span>注意：必须关闭相机缩放跟旋转</span>
    </div>

    <el-dialog v-model="dialogFormVisible" title="确认站点信息" width="25%">
      <el-form :model="form" label-position="right">
        <el-form-item label="X" :label-width="formLabelWidth">
          <el-input v-model="form.x" autocomplete="off" />
        </el-form-item>
        <el-form-item label="Z" :label-width="formLabelWidth">
          <el-input v-model="form.z" autocomplete="off" />
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="cancel">取消</el-button>
          <el-button type="primary" @click="confirm"> 确认 </el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { reactive, onMounted, onUnmounted, ref } from "vue";
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import utils from "@/utils";
import * as dat from "lil-gui";

// ----------------------------变量合集--------------------------
let canvas = null;
let baseBox = null; // html元素用于监听网页大小变化时渲染的宽高变化
const scene = new THREE.Scene();
const sizes = {
  width: 800,
  height: 600,
  aspect() {
    return this.width / this.height;
  },
};
// 辅助线
const axesHelper = new THREE.AxesHelper(100);
const gridHelper = new THREE.GridHelper(100, 100);
// scene.add(axesHelper);
scene.add(gridHelper);

// 几何体
const geometry = new THREE.BoxGeometry(90, 1, 40);
const material = new THREE.MeshBasicMaterial({
  color: 0xf5f5f5,
  transparent: true,
  opacity: 0.5,
});
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);

// --------------------------初始化------------------------------
let camera = null; // 相机
let controls = null; // 相机控制器
let renderer = null; // 渲染器

// 初始化函数 再mounted之后渲染
const initial = () => {
  canvas = document.querySelector("#webgl");
  baseBox = document.querySelector(".base");
  sizes.width = baseBox.clientWidth;
  sizes.height = baseBox.clientHeight;

  // 渲染器设置
  renderer = new THREE.WebGLRenderer({
    canvas: canvas,
    antialias: true,
  });

  renderer.setSize(sizes.width, sizes.height);
  //设置canvas的像素比为当前设备的屏幕像素比或者2之间的最小值，避免高分屏下模糊
  renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
  renderer.setClearColor("#90acc6");

  // 相机设置
  camera = new THREE.PerspectiveCamera(75, sizes.aspect(), 0.1, 1000);
  camera.position.set(0, 40, 0);
  scene.add(camera);
  // 相机控制器设置
  controls = new OrbitControls(camera, canvas);
  controls.enableRotate = false; //启用旋转
  controls.enableZoom = false; //禁止缩放
  controls.enableDamping = true; // 添加阻尼感

  tick();
};
const clock = new THREE.Clock();
const tick = () => {
  // 内置时钟 解决不同设备运行动画速率不一致的问题
  const elapsedTime = clock.getElapsedTime();
  controls.update();
  renderer.render(scene, camera);
  window.requestAnimationFrame(tick);
};

// ----------------------------表单相关--------------------------

const dialogFormVisible = ref(false);
const formLabelWidth = "40px";

const form = reactive({
  x: 0,
  z: 0,
});

const confirm = () => {
  createMesh();
};
const cancel = () => {
  dialogFormVisible.value = false;
};

// ----------------------------监听网页拉伸--------------------------
window.addEventListener("resize", () => {
  // Update sizes
  sizes.width = baseBox.clientWidth;
  sizes.height = baseBox.clientHeight;
  // Update camera
  camera.aspect = sizes.width / sizes.height;
  camera.updateProjectionMatrix();
  // Update renderer
  renderer.setSize(sizes.width, sizes.height);
  renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
});
// ----------------------------点击射线检测--------------------------
window.addEventListener("dblclick", (e) => {
  const result = utils.choose(e, sizes, camera, [mesh]); //射线拾取结果

  const point = result[0].point;
  form.x = point.x;
  form.z = point.z;

  //   createMesh(point.x, point.z, scene);
  dialogFormVisible.value = true;
});
onMounted(() => {
  console.log(utils);
  initial();
});

// 生成矩形 x,z-坐标 scene-场景
const createMesh = () => {
  const geometry = new THREE.BoxGeometry(4, 0, 2);
  // 材质
  const material = new THREE.MeshBasicMaterial({
    color: 0x3963bc,
    transparent: true,
    opacity: 1,
  });
  // 合成网格模型
  const mesh = new THREE.Mesh(geometry, material);
  mesh.name = "station";
  mesh.position.x = form.x;
  mesh.position.y = 0.6;
  mesh.position.z = form.z;
  scene.add(mesh);
  dialogFormVisible.value = false;
};

onUnmounted(() => {});
</script>
<style lang="scss" scoped>
.base {
  width: 100%;
  height: 100%;
  background-color: #ffffff;
  position: relative;
  #webgl {
    width: 100%;
    height: 100%;
  }
  .pannel {
    position: absolute;
    left: 0;
    top: 0;
    z-index: 1;
    width: 300px;
    min-height: 60px;
    border-bottom-right-radius: 40px;
    background-color: #08245f;
    color: #fff;
    padding: 10px;
    font-size: 14px;
    @include flex(column, flex-start, flex-start);
  }
}
</style>